/**
 * 优化后的聊天模块
 * 重构Vuex状态管理，提高性能和可维护性
 */

import { MESSAGE_TYPES, MESSAGE_STATUS, TIME_CONSTANTS } from '@/constants/messageTypes';
import { WEBSOCKET_COMMANDS } from '@/constants/websocketEvents';
import { timeUtils, arrayUtils, objectUtils } from '@/utils/common';

// 初始状态
const initialState = {
  // 消息相关
  messages: {}, // { chatId: [messages] }
  messageIdMap: {}, // { messageId: { chatId, index } }
  
  // 聊天相关
  currentChatId: null,
  currentChatType: 'single', // single | group
  chatList: [], // 聊天列表
  
  // 状态相关
  loading: false,
  endFlag: false,
  isSending: false,
  isConnected: false,
  shouldScroll: false,
  
  // 搜索相关
  searchUserId: null,
  searchGroupId: null,
  
  // 播放相关
  playingVoiceId: null,
  
  // 未读计数
  unreadCounts: {}, // { chatId: count }
  
  // 消息处理器
  messageHandlerFlag: null,
  
  // 性能优化
  messageCache: new Map(), // 消息缓存
  lastUpdateTime: 0,
  batchUpdateQueue: []
};

// 获取器
const getters = {
  // 获取指定聊天的消息
  getMessages: (state) => (chatId) => {
    return state.messages[chatId] || [];
  },

  // 获取群组消息
  getGroupMessages: (state) => (groupId) => {
    return state.messages[groupId] || [];
  },

  // 获取消息总数
  getMessageCount: (state) => (chatId) => {
    return state.messages[chatId]?.length || 0;
  },

  // 获取未读消息数
  getUnreadCount: (state) => (chatId) => {
    return state.unreadCounts[chatId] || 0;
  },

  // 获取总未读消息数
  getTotalUnreadCount: (state) => {
    return Object.values(state.unreadCounts).reduce((total, count) => total + count, 0);
  },

  // 获取最后一条消息
  getLastMessage: (state) => (chatId) => {
    const messages = state.messages[chatId];
    return messages && messages.length > 0 ? messages[messages.length - 1] : null;
  },

  // 获取消息状态
  getMessageStatus: (state) => (messageId) => {
    const messageInfo = state.messageIdMap[messageId];
    if (!messageInfo) return null;
    
    const message = state.messages[messageInfo.chatId]?.[messageInfo.index];
    return message ? message.status : null;
  },

  // 检查是否有新消息
  hasNewMessages: (state) => (chatId) => {
    const messages = state.messages[chatId];
    if (!messages || messages.length === 0) return false;
    
    const lastMessage = messages[messages.length - 1];
    return lastMessage && !lastMessage.isRead;
  },

  // 获取聊天统计信息
  getChatStats: (state) => (chatId) => {
    const messages = state.messages[chatId] || [];
    const stats = {
      total: messages.length,
      unread: state.unreadCounts[chatId] || 0,
      text: 0,
      image: 0,
      voice: 0,
      file: 0,
      other: 0
    };

    messages.forEach(message => {
      switch (message.messageType) {
        case MESSAGE_TYPES.TEXT:
          stats.text++;
          break;
        case MESSAGE_TYPES.IMAGE:
          stats.image++;
          break;
        case MESSAGE_TYPES.VOICE_MSG:
          stats.voice++;
          break;
        case MESSAGE_TYPES.FILE:
          stats.file++;
          break;
        default:
          stats.other++;
      }
    });

    return stats;
  }
};

// 变更
const mutations = {
  // 设置当前聊天
  SET_CURRENT_CHAT(state, { chatId, chatType = 'single' }) {
    state.currentChatId = chatId;
    state.currentChatType = chatType;
  },

  // 设置加载状态
  SET_LOADING(state, loading) {
    state.loading = loading;
  },

  // 设置结束标志
  SET_END_FLAG(state, endFlag) {
    state.endFlag = endFlag;
  },

  // 设置发送状态
  SET_SENDING_STATUS(state, isSending) {
    state.isSending = isSending;
  },

  // 设置连接状态
  SET_CONNECTION_STATUS(state, isConnected) {
    state.isConnected = isConnected;
  },

  // 设置自动滚动标志
  SET_SHOULD_SCROLL(state, shouldScroll) {
    state.shouldScroll = shouldScroll;
  },

  // 设置搜索用户ID
  SET_SEARCH_USER_ID(state, userId) {
    state.searchUserId = userId;
  },

  // 设置搜索群组ID
  SET_SEARCH_GROUP_ID(state, groupId) {
    state.searchGroupId = groupId;
  },

  // 设置播放语音ID
  SET_PLAYING_VOICE_ID(state, voiceId) {
    state.playingVoiceId = voiceId;
  },

  // 设置消息处理器标志
  SET_MESSAGE_HANDLER_FLAG(state, flag) {
    state.messageHandlerFlag = flag;
  },

  // 添加单条消息
  ADD_MESSAGE(state, { chatId, message }) {
    if (!state.messages[chatId]) {
      state.messages[chatId] = [];
    }

    // 检查消息是否已存在
    const existingIndex = state.messages[chatId].findIndex(msg => msg.id === message.id);
    if (existingIndex !== -1) {
      // 更新现有消息
      state.messages[chatId][existingIndex] = message;
      return;
    }

    // 添加新消息
    state.messages[chatId].push(message);
    
    // 更新消息ID映射
    const index = state.messages[chatId].length - 1;
    state.messageIdMap[message.id] = { chatId, index };

    // 更新最后更新时间
    state.lastUpdateTime = Date.now();
  },

  // 批量添加消息
  BATCH_ADD_MESSAGES(state, messages) {
    if (!Array.isArray(messages) || messages.length === 0) return;

    // 按聊天ID分组消息
    const groupedMessages = arrayUtils.groupBy(messages, 'chatId');

    // 批量更新每个聊天的消息
    Object.entries(groupedMessages).forEach(([chatId, chatMessages]) => {
      if (!state.messages[chatId]) {
        state.messages[chatId] = [];
      }

      // 去重并添加消息
      const existingIds = new Set(state.messages[chatId].map(msg => msg.id));
      const newMessages = chatMessages.filter(msg => !existingIds.has(msg.id));
      
      if (newMessages.length > 0) {
        state.messages[chatId].push(...newMessages);
        
        // 更新消息ID映射
        const startIndex = state.messages[chatId].length - newMessages.length;
        newMessages.forEach((message, index) => {
          state.messageIdMap[message.id] = {
            chatId,
            index: startIndex + index
          };
        });
      }
    });

    // 更新最后更新时间
    state.lastUpdateTime = Date.now();
  },

  // 设置消息列表
  SET_MESSAGES(state, { chatId, messages }) {
    state.messages[chatId] = messages || [];
    
    // 重建消息ID映射
    state.messageIdMap = {};
    state.messages[chatId].forEach((message, index) => {
      state.messageIdMap[message.id] = { chatId, index };
    });

    // 更新最后更新时间
    state.lastUpdateTime = Date.now();
  },

  // 更新消息
  UPDATE_MESSAGE(state, { messageId, updates }) {
    const messageInfo = state.messageIdMap[messageId];
    if (!messageInfo) return;

    const message = state.messages[messageInfo.chatId][messageInfo.index];
    if (message) {
      Object.assign(message, updates);
      state.lastUpdateTime = Date.now();
    }
  },

  // 撤回消息
  RETRACT_MESSAGE(state, { messageId, chatId }) {
    const messageInfo = state.messageIdMap[messageId];
    if (!messageInfo) return;

    const message = state.messages[messageInfo.chatId][messageInfo.index];
    if (message) {
      message.status = MESSAGE_STATUS.RETRACTED;
      message.content = '消息已撤回';
      state.lastUpdateTime = Date.now();
    }
  },

  // 删除消息
  DELETE_MESSAGE(state, { messageId, chatId }) {
    const messageInfo = state.messageIdMap[messageId];
    if (!messageInfo) return;

    const messages = state.messages[messageInfo.chatId];
    if (messages) {
      messages.splice(messageInfo.index, 1);
      
      // 重建消息ID映射
      state.messageIdMap = {};
      messages.forEach((message, index) => {
        state.messageIdMap[message.id] = { chatId: messageInfo.chatId, index };
      });
      
      state.lastUpdateTime = Date.now();
    }
  },

  // 标记消息为已读
  MARK_MESSAGES_READ(state, { chatId, messageIds }) {
    const messages = state.messages[chatId];
    if (!messages) return;

    if (Array.isArray(messageIds)) {
      // 批量标记指定消息为已读
      messageIds.forEach(messageId => {
        const messageInfo = state.messageIdMap[messageId];
        if (messageInfo && messageInfo.chatId === chatId) {
          const message = messages[messageInfo.index];
          if (message) {
            message.isRead = true;
            message.readTime = new Date().toISOString();
          }
        }
      });
    } else {
      // 标记所有消息为已读
      messages.forEach(message => {
        message.isRead = true;
        message.readTime = new Date().toISOString();
      });
    }

    // 重置未读计数
    state.unreadCounts[chatId] = 0;
    state.lastUpdateTime = Date.now();
  },

  // 更新未读计数
  UPDATE_UNREAD_COUNT(state, { chatId, increment = 1 }) {
    if (!state.unreadCounts[chatId]) {
      state.unreadCounts[chatId] = 0;
    }
    state.unreadCounts[chatId] += increment;
  },

  // 重置未读计数
  RESET_UNREAD_COUNT(state, chatId) {
    state.unreadCounts[chatId] = 0;
  },

  // 清空聊天历史
  CLEAR_CHAT_HISTORY(state, chatId) {
    if (state.messages[chatId]) {
      state.messages[chatId] = [];
    }
    state.unreadCounts[chatId] = 0;
    state.lastUpdateTime = Date.now();
  },

  // 清空所有消息
  CLEAR_ALL_MESSAGES(state) {
    state.messages = {};
    state.messageIdMap = {};
    state.unreadCounts = {};
    state.lastUpdateTime = Date.now();
  },

  // 重置状态
  RESET_STATE(state) {
    Object.assign(state, initialState);
  }
};

// 动作
const actions = {
  // 发送消息
  async sendMessage({ commit, state }, { chatId, message }) {
    try {
      commit('SET_SENDING_STATUS', true);
      
      // 添加临时消息到本地
      const tempMessage = {
        ...message,
        id: `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
        status: MESSAGE_STATUS.SENDING,
        createTime: new Date().toISOString(),
        isRead: false,
        isDelivered: false
      };
      
      commit('ADD_MESSAGE', { chatId, message: tempMessage });
      
      // 这里应该调用API发送消息
      // const result = await api.sendMessage(chatId, message);
      
      // 模拟API调用
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      // 更新消息状态
      commit('UPDATE_MESSAGE', {
        messageId: tempMessage.id,
        updates: {
          status: MESSAGE_STATUS.SENT,
          id: `real_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
        }
      });
      
      // 触发自动滚动
      commit('SET_SHOULD_SCROLL', true);
      
    } catch (error) {
      console.error('发送消息失败:', error);
      commit('UPDATE_MESSAGE', {
        messageId: message.id,
        updates: { status: MESSAGE_STATUS.FAILED }
      });
      throw error;
    } finally {
      commit('SET_SENDING_STATUS', false);
    }
  },

  // 撤回消息
  async retractMessage({ commit }, { messageId, chatId }) {
    try {
      // 这里应该调用API撤回消息
      // await api.retractMessage(messageId, chatId);
      
      commit('RETRACT_MESSAGE', { messageId, chatId });
    } catch (error) {
      console.error('撤回消息失败:', error);
      throw error;
    }
  },

  // 删除消息
  async deleteMessage({ commit }, { messageId, chatId }) {
    try {
      // 这里应该调用API删除消息
      // await api.deleteMessage(messageId, chatId);
      
      commit('DELETE_MESSAGE', { messageId, chatId });
    } catch (error) {
      console.error('删除消息失败:', error);
      throw error;
    }
  },

  // 标记消息为已读
  async markMessagesRead({ commit }, { chatId, messageIds }) {
    try {
      // 这里应该调用API标记已读
      // await api.markMessagesRead(chatId, messageIds);
      
      commit('MARK_MESSAGES_READ', { chatId, messageIds });
    } catch (error) {
      console.error('标记已读失败:', error);
      throw error;
    }
  },

  // 加载更多消息
  async loadMoreMessages({ commit, state }, { chatId, page = 1, pageSize = 20 }) {
    try {
      commit('SET_LOADING', true);
      
      // 这里应该调用API加载更多消息
      // const result = await api.getMessages(chatId, page, pageSize);
      
      // 模拟API调用
      await new Promise(resolve => setTimeout(resolve, 500));
      
      // 模拟返回的消息数据
      const messages = []; // result.messages
      
      if (messages.length > 0) {
        commit('BATCH_ADD_MESSAGES', messages);
      } else {
        commit('SET_END_FLAG', true);
      }
      
    } catch (error) {
      console.error('加载更多消息失败:', error);
      throw error;
    } finally {
      commit('SET_LOADING', false);
    }
  },

  // 清空聊天历史
  async clearChatHistory({ commit }, chatId) {
    try {
      // 这里应该调用API清空聊天历史
      // await api.clearChatHistory(chatId);
      
      commit('CLEAR_CHAT_HISTORY', chatId);
    } catch (error) {
      console.error('清空聊天历史失败:', error);
      throw error;
    }
  }
};

export default {
  namespaced: true,
  state: initialState,
  getters,
  mutations,
  actions
};
